package org.reborn.model.bound

import org.reborn.math._
import scala.collection.mutable.ArrayBuffer

/**
 * A bounding volume that is made up of at least 4 planes that 
 * point outward. An object inside the bound would be on the negative
 * side of all the planes. 
 * 
 */
class ConvexHull(val polygons:Seq[Polygon3F]) extends ClosedPolygonalBound{
  lazy val points:Seq[VectorF] = calcPoints
  lazy val edges:Seq[Line3F] = calcLines
  lazy val planes:Seq[Plane3F] = calcPlanes
  
  lazy val aabb:AxisAlignedBoundingBox = calcAabb
  lazy val center:VectorF = aabb.center
  
  private def calcPoints = {
	polygons.map((poly)=> poly.points).flatten.distinct
  }
  
  private def calcLines = {
	val uniqueLines = new ArrayBuffer[Line3F]()
	for(poly <- polygons; line <- poly.edges){
	  if(!uniqueLines.exists(_ containsSamePoints line))
	 	uniqueLines+=line
	}
	
	uniqueLines
  }
  
  private def calcPlanes = {
	polygons.map(_.plane)
  }
  
  private def calcAabb = {
	var min = Array[Float](Float.MaxValue,Float.MaxValue,Float.MaxValue)
	var max = Array[Float](Float.MinValue,Float.MinValue,Float.MinValue)
	
	var sides = new Array[VectorF](6)
	
	for(point <- points;
	    i <- 0 until 3){
	  if(point(i) < min(i)){ 
	 	min(i) = point(i)
	  }
	  if(point(i) > max(i)){ 
	 	max(i) = point(i)
	  }
	}
	
	new AxisAlignedBoundingBox(VectorF(min),VectorF(max))
  }
  
}